package cn.icare.cms;

import cn.icare.cms.model.enums.UserTypeEnum;
import cn.icare.cms.model.vo.rest.RespMsgVO;
import com.alibaba.fastjson.JSON;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * 自定义的网关过滤器
 */
public class TokenFilter extends ZuulFilter {


    private final String INVALID_TOKEN = "invalid token";

    /**
     * 需要登录验证Url地址列表
     */
    private final List<String> _requiredCheckUrls=Arrays.asList("/rest/personal/");

    /**
     * 不需要登录验证Url地址列表
     */

    private final List<String> _noCheckUrls=Arrays.asList("/microservice-app/rest/user/login","swagger"
            ,"api-docs","/microservice-mini","/microservice-app/rest/upload/image");


    /**
     * 过滤器类型 pre表示在请求之前进行逻辑操作
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 过滤器执行顺序
     * 当一个请求在同一个阶段存在多个过滤器的时候 过滤器的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 是否开启过滤
     */
    @Override
    public boolean shouldFilter() {

        RequestContext requestContext=RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //TODO 解决ZUUL跨域请求问题
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            return false;
        }
        //TODO 过滤as微服务,result微服务和login请求的鉴权验证
        String requstURI = request.getRequestURI();

        //先检查需要身份验证的Url
        if(_requiredCheckUrls!=null && _requiredCheckUrls.size()>0)
        {
            for (String url : _requiredCheckUrls) {
                if(requstURI.contains(url))
                {
                    return true;
                }
            }
        }

        //再检查免身份验证的Url
        if(_noCheckUrls!=null && _noCheckUrls.size()>0)
        {
            for (String url : _noCheckUrls) {
                if(requstURI.contains(url))
                {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 编写过滤器拦截业务逻辑代码
     */
    @Override
    public Object run() {
        //TODO 测试时如果需要访问swagger页面,可以先将鉴权判断全部注释掉
        //TODO 先从cookie中取token,如果cookie中没有,再从header中取
        RequestContext requestContext = RequestContext.getCurrentContext();
        TokenUtil tokenUtil = new TokenUtil();
        JwtUtil jwtUtil = new JwtUtil();
        String token = tokenUtil.getToken(requestContext.getRequest());

        String requstURI = requestContext.getRequest().getRequestURI();
        Integer userId=0;
        if(StringUtil.isNotEmpty(token)) {
            if (requstURI.contains("/microservice-mini/")) {
                //会员
                userId = jwtUtil.parseJWT(token, UserTypeEnum.Member.getCode());
            } else {
                userId = jwtUtil.parseJWT(token);
            }
        }

        if(userId ==null || userId==0)
        {
            this.setUnauthorizedResponse(requestContext);
        }
        return null;
    }

    private void setUnauthorizedResponse(RequestContext requestContext) {
        int code = HttpStatus.UNAUTHORIZED.value();
        requestContext.setSendZuulResponse(false);
        requestContext.setResponseStatusCode(code);
        RespMsgVO respMsgVO = new RespMsgVO(code, this.INVALID_TOKEN, null);
        requestContext.setResponseBody(JSON.toJSONString(respMsgVO));
    }
}
